package vg.modules.graph_comparison;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import org.apache.commons.lang.mutable.MutableBoolean;
import vg.modules.graph_comparison.components.AttrWeightTableDialog;
import vg.modules.graph_comparison.components.BigraphTableDialog;
import vg.modules.graph_comparison.components.RunDialog;
import vg.interfaces.ll_services.data_base_service.data.graph.Attribute;
import vg.interfaces.ll_services.data_base_service.data.graph.Edge;
import vg.interfaces.ll_services.data_base_service.data.graph.Graph;
import vg.interfaces.ll_services.data_base_service.data.graph.Vertex;
import vg.services.graph_view_manager.interfaces.graph_comparison.AGraphComparisonView;
import vg.services.graph_view_manager.interfaces.graph_comparison.InputGraphComparisonAlgorithmProperties;
import vg.services.graph_view_manager.interfaces.graph_comparison.OutputGraphComparisonAlgorithmProperties;
import vg.services.graph_view_manager.interfaces.graph_view.AGraphView;
import vg.services.graph_view_manager.interfaces.graph_view.GraphObserverAdapter;
import vg.services.graph_view_manager.interfaces.graph_view.IGraphObserver;
import vg.services.graph_view_manager.interfaces.graph_view.IGraphRenderer;
import vg.services.graph_view_manager.interfaces.tab.ATab;
import vg.services.graph_view_manager.realization.graph_view.smart_graph_view.realization.actions.GetSelectedSubGraph;
import vg.services.graph_view_manager.realization.graph_view.smart_graph_view.realization.actions.GraphObserverAction;
import vg.services.graph_view_manager.realization.graph_view.smart_graph_view.realization.actions.PopupMenuItemAction;
import vg.services.main_manager.VGMainServiceHelper;
import vg.services.plugin_manager.event_and_request.event.AUIEvent;
import vg.services.plugin_manager.event_and_request.event.UIEventChangeTab;
import vg.services.plugin_manager.event_and_request.event.UIEventOpenNewTab;
import vg.services.plugin_manager.event_and_request.request.UIRequestAddTab;
import vg.services.plugin_manager.interfaces.IPlugin;
import vg.services.user_interface_manager.interfaces.AUserInterfaceElement;
import vg.services.user_interface_manager.interfaces.UserInterfaceObserverAdapter;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

/**
 * Graph comparison plugin.
 *
 * @author Timur Zolotuhin (e-mail: tzolotuhin@gmail.com)
 */
public class GraphComparisonPlugin extends AUserInterfaceElement implements IPlugin {
    // Defines
    private final static String SHOW_INTERSECTION_ITEM = "Show intersection";
    private final static String SHOW_FIRST_GRAPH_ITEM = "Show first graph";
    private final static String SHOW_SECOND_GRAPH_ITEM = "Show second graph";

    // Mutex
    private final Object generalMutex = new Object();

    // Swing components
    private JToolBar toolBar;
    private JButton attrWeightTableButton, bigraphTableButton, runButton;
    private JComboBox showComboBox;

    // Main data
    private AGraphComparisonView currentGraphComparisonView;
    private AGraphView currentGraphView;
    private int currentTabType = ATab.DEF_UNKNOWN_TAB_TYPE;
    private int currentTabId = -1;

    private IGraphObserver observer;

    private JMenuItem compareGraphsMenuItem, uniteVerticesMenuItem, separateVerticesMenuItem;
    private JMenuItem removeVerticesFromListsMenuItem;

    public GraphComparisonPlugin() {
        super("Graph comparison toolbar", null);
    }

    @Override
	public void install() throws Exception {
        toolBar = new JToolBar();
        toolBar.setFloatable(false);

        attrWeightTableButton = new JButton(new ImageIcon("./data/resources/textures/graph_comparison/weight.png"));
        attrWeightTableButton.setToolTipText("Weight of attributes for comparison of two graphs");
        attrWeightTableButton.setEnabled(false);
        attrWeightTableButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                AttrWeightTableDialog.show(currentGraphComparisonView);
            }
        });

        bigraphTableButton = new JButton(new ImageIcon("./data/resources/textures/graph_comparison/bigraph.png"));
        bigraphTableButton.setToolTipText("Bigraph table for comparison of two graphs");
        bigraphTableButton.setEnabled(false);
        bigraphTableButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                BigraphTableDialog.show(currentGraphComparisonView);
            }
        });

        runButton = new JButton(new ImageIcon("./data/resources/textures/graph_comparison/run.png"));
        runButton.setToolTipText("Run comparison of two graphs");
        runButton.setEnabled(false);
        runButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                RunDialog.show(currentGraphComparisonView);
            }
        });

        showComboBox = new JComboBox<String>();
        showComboBox.addItem(SHOW_INTERSECTION_ITEM);
        showComboBox.addItem(SHOW_FIRST_GRAPH_ITEM);
        showComboBox.addItem(SHOW_SECOND_GRAPH_ITEM);
        showComboBox.setMaximumSize(showComboBox.getPreferredSize());
        showComboBox.setEnabled(false);
        showComboBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Object item = showComboBox.getSelectedItem();
                if (item != null && item.equals(SHOW_INTERSECTION_ITEM)) {
                    synchronized (generalMutex) {
                        currentGraphComparisonView.show(AGraphComparisonView.SHOW_GRAPH_INTERSECTION);
                    }
                } else if (item != null && item.equals(SHOW_FIRST_GRAPH_ITEM)) {
                    synchronized (generalMutex) {
                        currentGraphComparisonView.show(AGraphComparisonView.SHOW_FIRST_GRAPH);
                    }
                } else if (item != null && item.equals(SHOW_SECOND_GRAPH_ITEM)) {
                    synchronized (generalMutex) {
                        currentGraphComparisonView.show(AGraphComparisonView.SHOW_SECOND_GRAPH);
                    }
                }
            }
        });

        toolBar.add(attrWeightTableButton);
        toolBar.add(bigraphTableButton);
        toolBar.add(runButton);
        toolBar.add(showComboBox);

        VGMainServiceHelper.userInterfaceManager.addInstrument(this);

        VGMainServiceHelper.userInterfaceManager.addObserver(new UserInterfaceObserverAdapter() {
            @Override
            public void dispatchEvent(AUIEvent event) {
                switch (event.getType()) {
                    case DEF_CHANGE_UI_STYLE: {
                        SwingUtilities.updateComponentTreeUI(toolBar);
                        break;
                    }

                    case DEF_CHANGE_TAB: {
                        UIEventChangeTab bufEvent = (UIEventChangeTab)event;
                        currentTabId = bufEvent.getTabId();
                        changeView(bufEvent.getTab());
                        break;
                    }

                    case DEF_OPEN_NEW_TAB: {
                        UIEventOpenNewTab bufEvent = (UIEventOpenNewTab)event;
                        ATab tab = bufEvent.getTab();
                        changeView(tab);
                        if (tab != null) {
                            switch (tab.getTabType()) {
                                case ATab.DEF_GRAPH_COMPARISON_TAB_TYPE: {
                                    currentGraphComparisonView = (AGraphComparisonView)tab;
                                    RunDialog.show(currentGraphComparisonView);
                                    break;
                                }

                                default: break;
                            }
                        }
                        break;
                    }

                    default: break;
                }
            }
        });

        // compare two inner graphs
        compareGraphsMenuItem = new JMenuItem("compare two inner graphs");
        compareGraphsMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                synchronized (generalMutex) {
                    currentGraphView.addAction(new GetSelectedSubGraph(GetSelectedSubGraph.GET_ORIGINAL_SELECTED_SUBGRAPH_MODE) {
                        @Override
                        public void finishAction(IGraphRenderer graphRenderer) {
                            Graph graph = getSelectedSubGraph();
                            if (graph != null && !graph.isEmpty()) {
                                Collection<Vertex> vertices = graph.getVertices();
                                if (vertices != null && vertices.size() == 2) {
                                    Iterator<Vertex> it = vertices.iterator();
                                    Vertex v1 = it.next();
                                    Vertex v2 = it.next();
                                    if (v1 != null && v2 != null && v1.isInnerGraph() && v2.isInnerGraph()) {
                                        Graph graph1 = v1.getInnerGraph();
                                        Graph graph2 = v2.getInnerGraph();

                                        Graph innerGraph1 = VGMainServiceHelper.graphDataBaseManager.getGraph(graph1.getStorableId());
                                        Graph innerGraph2 = VGMainServiceHelper.graphDataBaseManager.getGraph(graph2.getStorableId());

                                        AGraphComparisonView graphComparisonView = VGMainServiceHelper.graphViewManager.newGraphComparison(innerGraph1, innerGraph2);
                                        VGMainServiceHelper.userInterfaceManager.sendRequest(new UIRequestAddTab(graphComparisonView));
                                    } else {
                                        VGMainServiceHelper.windowMessenger.errorMessage("Need select two vertices with inner graphs", "Error");
                                    }
                                } else {
                                    VGMainServiceHelper.windowMessenger.errorMessage("Need select two vertices with inner graphs", "Error");
                                }
                            }
                        }
                    });
                }
            }
        });

        uniteVerticesMenuItem = new JMenuItem("unite two vertices");
        uniteVerticesMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                synchronized (generalMutex) {
                    currentGraphView.addAction(new GetSelectedSubGraph(GetSelectedSubGraph.GET_ORIGINAL_SELECTED_SUBGRAPH_MODE) {
                        @Override
                        public void finishAction(IGraphRenderer graphRenderer) {
                            synchronized (generalMutex) {
                                Graph graph = getSelectedSubGraph();
                                if (graph != null && !graph.isEmpty()) {
                                    Collection<Vertex> vertices = graph.getVertices();
                                    if (vertices != null && vertices.size() == 2) {
                                        Iterator<Vertex> it = vertices.iterator();
                                        Vertex v1 = it.next();
                                        Vertex v2 = it.next();

                                        OutputGraphComparisonAlgorithmProperties output = currentGraphComparisonView.getOutputGraphComparisonAlgorithmProperties();
                                        BiMap<Vertex, Vertex> outputGraphVertices2firstOriginalGraphVertices = output.getOutputGraphVertices2firstOriginalGraphVertices();
                                        BiMap<Vertex, Vertex> outputGraphVertices2secondOriginalGraphVertices = output.getOutputGraphVertices2secondOriginalGraphVertices();

                                        Vertex originalVertex1;
                                        Vertex originalVertex2;

                                        if (outputGraphVertices2firstOriginalGraphVertices != null) {
                                            originalVertex1 = outputGraphVertices2firstOriginalGraphVertices.get(v1);
                                        } else {
                                            VGMainServiceHelper.windowMessenger.errorMessage("outputGraphVertices2firstOriginalGraphVertices = null", "Error");
                                            return;
                                        }

                                        if (outputGraphVertices2secondOriginalGraphVertices != null) {
                                            originalVertex2 = outputGraphVertices2secondOriginalGraphVertices.get(v2);
                                        } else {
                                            VGMainServiceHelper.windowMessenger.errorMessage("outputGraphVertices2secondOriginalGraphVertices = null", "Error");
                                            return;
                                        }

                                        // try invert
                                        if (originalVertex1 == null || originalVertex2 == null) {
                                            originalVertex1 = outputGraphVertices2firstOriginalGraphVertices.get(v2);
                                            originalVertex2 = outputGraphVertices2secondOriginalGraphVertices.get(v1);
                                        }

                                        if (originalVertex1 == null || originalVertex2 == null) {
                                            VGMainServiceHelper.windowMessenger.errorMessage("Need select two vertices from different graphs", "Error");
                                        } else {
                                            InputGraphComparisonAlgorithmProperties input = currentGraphComparisonView.getCurrentInputGraphComparisonAlgorithmProperties();
                                            BiMap<Vertex, Vertex> unitedVertices = input.getUnitedVertices();
                                            if (unitedVertices == null) {
                                                unitedVertices = HashBiMap.create();
                                            }

                                            if (unitedVertices.containsKey(originalVertex1)) {
                                                unitedVertices.remove(originalVertex1);
                                                VGMainServiceHelper.windowMessenger.warningMessage("List for united vertices contains selected vertex, already. It will replaced on new.", "Warning");
                                            }

                                            if (unitedVertices.inverse().containsKey(originalVertex2)) {
                                                unitedVertices.inverse().remove(originalVertex2);
                                                VGMainServiceHelper.windowMessenger.warningMessage("List for united vertices contains selected vertex, already. It will replaced on new.", "Warning");
                                            }

                                            BiMap<Vertex, Vertex> separatedVertices = input.getSeparatedVertices();
                                            if (separatedVertices != null) {
                                                separatedVertices.remove(originalVertex1);
                                            }

                                            unitedVertices.put(originalVertex1, originalVertex2);

                                            input.setUnitedVertices(unitedVertices);
                                            input.setSeparatedVertices(separatedVertices);
                                            currentGraphComparisonView.setInputGraphComparisonAlgorithmProperties(input);
                                        }
                                    } else {
                                        VGMainServiceHelper.windowMessenger.errorMessage("Need select two vertices for unite it", "Error");
                                    }
                                }
                            }
                        }
                    });
                }
            }
        });

        separateVerticesMenuItem = new JMenuItem("separate two vertices");
        separateVerticesMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                synchronized (generalMutex) {
                    currentGraphView.addAction(new GetSelectedSubGraph(GetSelectedSubGraph.GET_ORIGINAL_SELECTED_SUBGRAPH_MODE) {
                        @Override
                        public void finishAction(IGraphRenderer graphRenderer) {
                            synchronized (generalMutex) {
                                Graph graph = getSelectedSubGraph();
                                if (graph != null && !graph.isEmpty()) {
                                    Collection<Vertex> vertices = graph.getVertices();
                                    if (vertices != null && (vertices.size() == 2 || vertices.size() == 1)) {
                                        Iterator<Vertex> it = vertices.iterator();
                                        Vertex v1 = it.next();
                                        Vertex v2 = vertices.size() == 2 ? it.next() : v1;

                                        OutputGraphComparisonAlgorithmProperties output = currentGraphComparisonView.getOutputGraphComparisonAlgorithmProperties();
                                        BiMap<Vertex, Vertex> outputGraphVertices2firstOriginalGraphVertices = output.getOutputGraphVertices2firstOriginalGraphVertices();
                                        BiMap<Vertex, Vertex> outputGraphVertices2secondOriginalGraphVertices = output.getOutputGraphVertices2secondOriginalGraphVertices();

                                        Vertex originalVertex1;
                                        Vertex originalVertex2;

                                        if (outputGraphVertices2firstOriginalGraphVertices != null) {
                                            originalVertex1 = outputGraphVertices2firstOriginalGraphVertices.get(v1);
                                        } else {
                                            VGMainServiceHelper.windowMessenger.errorMessage("outputGraphVertices2firstOriginalGraphVertices = null", "Error");
                                            return;
                                        }

                                        if (outputGraphVertices2secondOriginalGraphVertices != null) {
                                            originalVertex2 = outputGraphVertices2secondOriginalGraphVertices.get(v2);
                                        } else {
                                            VGMainServiceHelper.windowMessenger.errorMessage("outputGraphVertices2secondOriginalGraphVertices = null", "Error");
                                            return;
                                        }

                                        // try invert
                                        if (originalVertex1 == null || originalVertex2 == null) {
                                            originalVertex1 = outputGraphVertices2firstOriginalGraphVertices.get(v2);
                                            originalVertex2 = outputGraphVertices2secondOriginalGraphVertices.get(v1);
                                        }

                                        if (originalVertex1 == null || originalVertex2 == null) {
                                            VGMainServiceHelper.windowMessenger.errorMessage("Need select two vertices from different graphs or select one vertex from general vertices of two graphs", "Error");
                                        } else {
                                            InputGraphComparisonAlgorithmProperties input = currentGraphComparisonView.getCurrentInputGraphComparisonAlgorithmProperties();
                                            BiMap<Vertex, Vertex> separatedVertices = input.getSeparatedVertices();
                                            if (separatedVertices == null) {
                                                separatedVertices = HashBiMap.create();
                                            }

                                            if (separatedVertices.containsKey(originalVertex1)) {
                                                separatedVertices.remove(originalVertex1);
                                                VGMainServiceHelper.windowMessenger.warningMessage("List for separated vertices contains selected vertex, already. It will replaced on new.", "Warning");
                                            }

                                            if (separatedVertices.inverse().containsKey(originalVertex2)) {
                                                separatedVertices.inverse().remove(originalVertex2);
                                                VGMainServiceHelper.windowMessenger.warningMessage("List for separated vertices contains selected vertex, already. It will replaced on new.", "Warning");
                                            }

                                            BiMap<Vertex, Vertex> unitedVertices = input.getUnitedVertices();
                                            if (unitedVertices != null) {
                                                unitedVertices.remove(originalVertex1);
                                            }

                                            separatedVertices.put(originalVertex1, originalVertex2);

                                            input.setUnitedVertices(unitedVertices);
                                            input.setSeparatedVertices(separatedVertices);
                                            currentGraphComparisonView.setInputGraphComparisonAlgorithmProperties(input);
                                        }
                                    } else {
                                        VGMainServiceHelper.windowMessenger.errorMessage("Need select two or one vertices for separate it", "Error");
                                    }
                                }
                            }
                        }
                    });
                }
            }
        });

        removeVerticesFromListsMenuItem = new JMenuItem("Unpin from separated and united list");
        removeVerticesFromListsMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                synchronized (generalMutex) {
                    currentGraphView.addAction(new GetSelectedSubGraph(GetSelectedSubGraph.GET_ORIGINAL_SELECTED_SUBGRAPH_MODE) {
                        @Override
                        public void finishAction(IGraphRenderer graphRenderer) {
                            synchronized (generalMutex) {
                                Graph graph = getSelectedSubGraph();
                                if (graph != null && !graph.isEmpty()) {
                                    Collection<Vertex> vertices = graph.getVertices();
                                    if (vertices != null) {
                                        OutputGraphComparisonAlgorithmProperties output = currentGraphComparisonView.getOutputGraphComparisonAlgorithmProperties();
                                        BiMap<Vertex, Vertex> outputGraphVertices2firstOriginalGraphVertices = output.getOutputGraphVertices2firstOriginalGraphVertices();
                                        BiMap<Vertex, Vertex> outputGraphVertices2secondOriginalGraphVertices = output.getOutputGraphVertices2secondOriginalGraphVertices();

                                        InputGraphComparisonAlgorithmProperties input = currentGraphComparisonView.getCurrentInputGraphComparisonAlgorithmProperties();
                                        BiMap<Vertex, Vertex> separatedVertices = input.getSeparatedVertices();
                                        BiMap<Vertex, Vertex> unitedVertices = input.getUnitedVertices();

                                        for (Vertex v : vertices) {
                                            Vertex originalVertex;

                                            if (outputGraphVertices2firstOriginalGraphVertices != null) {
                                                originalVertex = outputGraphVertices2firstOriginalGraphVertices.get(v);
                                            } else {
                                                VGMainServiceHelper.windowMessenger.errorMessage("outputGraphVertices2firstOriginalGraphVertices = null", "Error");
                                                return;
                                            }

                                            if (originalVertex != null) {
                                                if (unitedVertices != null) {
                                                    unitedVertices.remove(originalVertex);
                                                }

                                                if (separatedVertices != null) {
                                                    separatedVertices.remove(originalVertex);
                                                }
                                            } else {
                                                originalVertex = outputGraphVertices2secondOriginalGraphVertices.get(v);
                                                if (originalVertex != null) {
                                                    if (unitedVertices != null) {
                                                        unitedVertices.inverse().remove(originalVertex);
                                                    }

                                                    if (separatedVertices != null) {
                                                        separatedVertices.inverse().remove(originalVertex);
                                                    }
                                                }
                                            }
                                        }

                                        input.setUnitedVertices(unitedVertices);
                                        input.setSeparatedVertices(separatedVertices);
                                        currentGraphComparisonView.setInputGraphComparisonAlgorithmProperties(input);
                                    }
                                }
                            }
                        }
                    });
                }
            }
        });

        observer = new GraphObserverAdapter() {
            @Override
            public void updateSelectedElements(Map<Vertex, Map<Attribute, MutableBoolean>> selectedVertex, Map<Edge, Map<Attribute, MutableBoolean>> selectedEdge) {
                synchronized (generalMutex) {
                    currentGraphView.addAction(new PopupMenuItemAction(PopupMenuItemAction.REMOVE_ITEM_ACTION, uniteVerticesMenuItem));
                    currentGraphView.addAction(new PopupMenuItemAction(PopupMenuItemAction.REMOVE_ITEM_ACTION, separateVerticesMenuItem));
                    currentGraphView.addAction(new PopupMenuItemAction(PopupMenuItemAction.REMOVE_ITEM_ACTION, removeVerticesFromListsMenuItem));
                    if (selectedEdge.isEmpty() && selectedVertex.size() >= 1 && selectedVertex.size() <= 2) {
                        currentGraphView.addAction(new PopupMenuItemAction(PopupMenuItemAction.ADD_ITEM_ACTION, uniteVerticesMenuItem));
                        currentGraphView.addAction(new PopupMenuItemAction(PopupMenuItemAction.ADD_ITEM_ACTION, separateVerticesMenuItem));
                    }

                    if (selectedVertex.size() >= 1 ) {
                        currentGraphView.addAction(new PopupMenuItemAction(PopupMenuItemAction.ADD_ITEM_ACTION, removeVerticesFromListsMenuItem));
                    }
                }
            }
        };
	}

    @Override
    public JComponent getView() {
        return toolBar;
    }

//==============================================================================
//-----------------PRIVATE METHODS----------------------------------------------
    private void changeView(final ATab tab) {
        // if it's not EDT
        if (!SwingUtilities.isEventDispatchThread()) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    changeView(tab);
                }
            });
            return;
        }

        // otherwise (it's EDT)
        synchronized (generalMutex) {
            if (currentGraphView != null) {
                currentGraphView.addAction(new PopupMenuItemAction(PopupMenuItemAction.REMOVE_ITEM_ACTION, compareGraphsMenuItem));
                currentGraphView.addAction(new PopupMenuItemAction(PopupMenuItemAction.REMOVE_ITEM_ACTION, uniteVerticesMenuItem));
                currentGraphView.addAction(new PopupMenuItemAction(PopupMenuItemAction.REMOVE_ITEM_ACTION, separateVerticesMenuItem));
                currentGraphView.addAction(new GraphObserverAction(GraphObserverAction.REMOVE_SELECT_OBSERVER_ACTION, observer));
            }

            currentGraphComparisonView = null;
            currentGraphView = null;
            currentTabType = ATab.DEF_UNKNOWN_TAB_TYPE;

            if (tab != null) {
                currentTabType = tab.getTabType();

                switch (tab.getTabType()) {
                    case ATab.DEF_GRAPH_COMPARISON_TAB_TYPE: {
                        currentGraphComparisonView = (AGraphComparisonView)tab;
                        currentGraphView = currentGraphComparisonView.getMainGraphView();
                        if (currentGraphView != null) {
                            currentGraphView.addAction(new GraphObserverAction(GraphObserverAction.ADD_SELECT_OBSERVER_ACTION, observer));
                        }
                        break;
                    }

                    case ATab.DEF_GRAPH_VIEW_TAB_TYPE: {
                        currentGraphView = (AGraphView)tab;
                        currentGraphView.addAction(new PopupMenuItemAction(PopupMenuItemAction.ADD_ITEM_ACTION, compareGraphsMenuItem));
                        break;
                    }

                    default:
                        break;
                }
            }

            // update buttons
            if (currentGraphComparisonView == null) {
                attrWeightTableButton.setEnabled(false);
                bigraphTableButton.setEnabled(false);
                runButton.setEnabled(false);
                showComboBox.setEnabled(false);
            } else {
                attrWeightTableButton.setEnabled(true);
                bigraphTableButton.setEnabled(true);
                runButton.setEnabled(true);
                showComboBox.setEnabled(true);
            }
        }
    }
}
